package minicad;
import java.awt.*;
import javax.swing.*;

import java.awt.event.*;
import java.util.HashMap;
import java.util.Map;

enum State {
    DRAW,SELECT
}
enum DrawState {
    LINE,RECT,CIRC,TEXT
}
class Controller {
    Model model;

    State state = State.DRAW;
    DrawState drawState = DrawState.LINE;// only effective if state==DRAW!
    Shape s_shape = null;
    
    int start_x,start_y; // for dragging

    String[] colorStrings = 
        new String[]{"blue","green","red"};
    Color[] colors = 
        new Color[]{Color.BLUE,Color.GREEN,Color.RED};
    Map<String,Color> colorMap = new HashMap<>();

    String[] drawStateStrings = 
        new String[]{"Line","Rect","Circ","Text"};
    DrawState[] drawStates = 
        new DrawState[]{DrawState.LINE,DrawState.RECT,DrawState.CIRC,DrawState.TEXT};
    Map<String,DrawState> drawStateMap = new HashMap<>();
    
    Controller(Model model) {
        this.model = model;
        for(int i = 0;i<colors.length;++i) {
            colorMap.put(colorStrings[i], colors[i]);
        }
        for(int i = 0;i<drawStates.length;++i) {
            drawStateMap.put(drawStateStrings[i], drawStates[i]);
        }
    }
    void reset() {
        state = State.DRAW;
        drawState = DrawState.LINE;
        s_shape = null;
    }
    void addStateControl(JButton selectButton) {
        /**
         * Controling DRAW or SELECT
         */
        selectButton.addActionListener(
            new ActionListener()
            {
                public void actionPerformed(ActionEvent e) {
                    if(state==State.DRAW) state = State.SELECT;
                    else if(state==State.SELECT) {
                        state = State.DRAW;
                        s_shape = null;
                    }
                    System.out.println(state);
                };
            }
        );
    }
    void addDrawStateControl(JButton[] drawButtons) {
        for(int i = 0; i<drawButtons.length;++i){
            JButton button = drawButtons[i];
            String text = button.getText();
            System.out.println(text);
            button.addActionListener(
                new ActionListener(){
                    public void actionPerformed(ActionEvent e) {
                        if(state != State.DRAW) return;
                        drawState = drawStateMap.get(text);
                        System.out.println(drawState);
                    };
                }
            );
        }
    }
    void addDrawControl(JFrame frame, JPanel panel) {
        panel.addMouseListener(
            new MouseAdapter() {
                int x1,y1,x2,y2;
                public void mousePressed(MouseEvent e) {
                    if(state!=State.DRAW) return;
                    x1 = e.getX(); y1 = e.getY();
                };
                public void mouseReleased(MouseEvent e) {
                    if(state != State.DRAW) return;
                    x2 = e.getX();y2 = e.getY();
                    switch (drawState) {
                        case LINE:
                            model.add(new Line(x1,y1,x2,y2));
                            break;
                        case RECT:
                            model.add(new Rect(x1, y1, x2, y2));
                            break;
                        case CIRC:
                            int x = (x1+x2)/2;
                            int y = (y1+y2)/2;
                            double r = 0.5 * Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))/ Math.sqrt(2);
                            model.add(new Circ(x,y,r));
                            break;
                        case TEXT:
                            String text = JOptionPane.showInputDialog(frame, "Please Enter the Text");
                            if (text == null)return;
                            model.add(new Text(text, x2,y2));
                            break;
                        default:
                            break;
                    }
                };
            }
        );
    }
    void addSelectControl(JPanel panel){
        panel.addMouseListener(
            new MouseAdapter() {
                public void mousePressed(MouseEvent e) {
                    if(state==State.DRAW)return;
                    int x = start_x = e.getX(), y = start_y = e.getY();
                    s_shape = model.select(x,y);
                };
            }
        );
        panel.addMouseMotionListener(
            new MouseAdapter(){
                public void mouseDragged(MouseEvent e) {
                    if(s_shape==null) return;
                    int x = e.getX(),y = e.getY();
                    int dx = x - start_x, dy = y-start_y;
                    model.move(s_shape, dx, dy);
                    start_x = x;start_y = y;
                };
            }
        );
    }
    void addModControl(JTextField textField,JButton upButton, JButton downButton) {
        // select and mod color use text input
        textField.addKeyListener(
            new KeyAdapter() {
                public void keyPressed(KeyEvent e) {
                    if(state==State.DRAW || s_shape==null)return;
                    if(e.getKeyCode()==KeyEvent.VK_ENTER){
                        String color_name = textField.getText();
                        model.set_color(s_shape, colorMap.get(color_name));
                    }
                };
            } 
        );
        // use button to scale up and down
        upButton.addActionListener(
            new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    if(state==State.DRAW || s_shape==null)return;
                    double scale_up = 1.2;
                    model.scale(s_shape, scale_up);
                };
            }
        );
        downButton.addActionListener(
            new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    if(state==State.DRAW || s_shape==null)return;
                    double scale_down = 0.8;
                    model.scale(s_shape, scale_down);
                };
            }
        );
    }

    void addFileControl(JMenuItem openItem, JMenuItem saveItem, FileDialog openDiag,FileDialog saveDiag) {
        openItem.addActionListener(
            new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    openDiag.setVisible(true);
                    String filename = openDiag.getFile();
                    System.out.println(filename);
                    model.loadShapeList(filename);
                    reset();
                };
            }
        );
        saveItem.addActionListener(
            new ActionListener(){
                public void actionPerformed(ActionEvent e) {
                    saveDiag.setVisible(true);
                    String filename = saveDiag.getFile();
                    System.out.println(filename);
                    model.dumpShapeList(filename);
                };
            }
        );

    }
}